package in.falkeninc.umt_v0_9_8_1;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import java.util.ArrayList;

import android.app.PendingIntent.OnFinished;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;
import android.util.Log;

public class DatabaseHandler extends SQLiteOpenHelper {

	// All Static variables
	// Database Version
	private static final int DATABASE_VERSION = 10;

	// Database Name
	private static final String DATABASE_NAME = "alarmManager";

	// Alarm table name
	private static final String TABLE_ALARMS = "alarms4";

	// Alarms Table Columns names
	private static final String KEY_ID = "_id";
	private static final String KEY_NAME = "name";
	private static final String KEY_DESCR = "description";
	private static final String KEY_ALARMTIME = "alarmtime";
	private static final String KEY_ICON = "icon";
	private static final String KEY_ENABLED = "enabled";
	private static final String KEY_REPEATS = "repeats";
	private static final String KEY_SNOOZE = "snooze";
	//------
	private static final String KEY_ALARMRND = "alarmrnd";
	private static final String KEY_RNDREPS = "rndreps";
	private static final String KEY_DAYCODE = "daycode";
	private static final String KEY_WEEKCODE = "weekcode";
	private static final String KEY_MONTHCODE = "monthcode";
	private static final String KEY_CONFIRM = "confirm";
	private static final String KEY_ALARMDELAY = "alarmdelay";
	private static final String KEY_ALARMTRESHOLD = "alarmthreshold";
	private static final String KEY_PHONE1 = "phone1";
	private static final String KEY_PHONE2 = "phone2";
	private static final String KEY_URL = "url";
	private static final String KEY_RETURNMSG = "returnmsg";
	private static final String KEY_BROADCASTMSG = "broadcastmsg";
	private static final String KEY_ACTIONCODE = "actioncode";
	private static final String KEY_GPS = "gps";
	private static final String KEY_XSTR1 = "xstr1";
	private static final String KEY_XSTR2 = "xstr2";
	private static final String KEY_XINT1 = "xint1";
	private static final String KEY_XINT2 = "xint2";
	private static final String KEY_XL1 = "xl1";
	private static final String KEY_XL2 = "xl2";

	public DatabaseHandler(Context context) {
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
	}
	
	public enum db_mode {
		NONE, SORTED
	}

	// Creating Tables
	@Override
	public void onCreate(SQLiteDatabase db) {
		
		String CREATE_ALARMS_TABLE = "CREATE TABLE " + TABLE_ALARMS + " (" + 
										KEY_ID 			+ " INTEGER PRIMARY KEY, " +// ID 
										KEY_NAME 		+ " TEXT, " + 				// TIMER NAME
										KEY_DESCR 		+ " TEXT, " + 				// DESCRIPTION
										KEY_ALARMTIME 	+ " LONG, " + 				// ALARM SET FOR THIS TIME
										KEY_ICON 		+ " INTEGER, " +			// Which icon of a few included ones to set for the row when view
										KEY_ENABLED 	+ " INTEGER, " +			// ALARM ENABLED/DISABLED
										KEY_REPEATS 	+ " INTEGER, " +			// How many times to repeat alarm before stopping
										KEY_DAYCODE 	+ " TEXT, " +				// String that can be deciphered into a day-by-day scheme. 
										KEY_SNOOZE 		+ " INTEGER, " +			// Snooze ENABLE/DISABLE
										// not engaged yet
										KEY_ALARMRND 	+ " LONG, " + 				// When this is != 0, the alarm will go off  KEY_REPEATS times, between KEY_ALARMTIME and this time
										KEY_RNDREPS 	+ " INTEGER, " +			// How many repeats to repeat the alarm after snoozing doesnt help :p
										KEY_WEEKCODE 	+ " TEXT, " +				// ...
										KEY_MONTHCODE 	+ " TEXT, " +				// ...
										KEY_CONFIRM 	+ " INTEGER, " +            // Confirmation ENABLE/DISABLE
										KEY_ALARMDELAY 	+ " LONG, " +				// Length of a delay if you start a timer where you already just did the required task required. 
										KEY_ALARMTRESHOLD + " LONG, " +				// The deadline threshold that can start the affirmative action sequence
										KEY_PHONE1 		+ " TEXT, " +               // Primary broadcast phone number (this is your friend or something). If you get a Phone/SMS back, it wont contact the backup.
										KEY_PHONE2 		+ " TEXT, " +				// Backup broadcast
										KEY_URL 		+ " TEXT, " +				// Complete server URL (http:/action.com:123/task.php?action=KEY_MESSAGE
										KEY_RETURNMSG 	+ " TEXT, "	+				// The message (if any that was returned from one of the Broadcast phones or server message)
										KEY_BROADCASTMSG+ " TEXT, " +				// Broadcasted message if threshold reached
										KEY_ACTIONCODE 	+ " TEXT, " +				// Action code, maybe human readable
										KEY_GPS 		+ " TEXT, " +				// GPS log, optional
										KEY_XSTR1 		+ " TEXT, " +				// Extra columns for good measure
										KEY_XSTR2 		+ " TEXT, " +				// Extra columns for good measure
										KEY_XINT1 		+ " INTEGER, " +			// Extra columns for good measure
										KEY_XINT2 		+ " INTEGER, " +			// Extra columns for good measure
										KEY_XL1 		+ " LONG, " +				// Extra columns for good measure
										KEY_XL2 		+ " LONG " +				// Extra columns for good measure
										");";

		db.execSQL(CREATE_ALARMS_TABLE);
		
		
	}

	// Upgrading database
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		
		// Drop older table if existed
		db.execSQL("DROP TABLE IF EXISTS " + TABLE_ALARMS);

		// Create tables again
		onCreate(db);
	}

	/**
	 * All CRUD(Create, Read, Update, Delete) Operations
	 */

	// Adding new alarm
	int addAlarm(AlarmInfo alarm) {
		
		SQLiteDatabase db = this.getWritableDatabase();
		ContentValues values = new ContentValues();
		long genid = 0;
		
		values.put(KEY_NAME, alarm.getName()); // alarm name
		values.put(KEY_DESCR, alarm.getDescription()); // alarm description
		values.put(KEY_ALARMTIME, alarm.getAlarmtime()); // alarm time
		values.put(KEY_ICON, alarm.getIcon()); // alarm time
		values.put(KEY_ENABLED, alarm.getEnabled()); // alarm time
		values.put(KEY_REPEATS, alarm.getRepeats()); // alarm time
		values.put(KEY_DAYCODE, alarm.getDaycode()); // alarm time
		values.put(KEY_SNOOZE, alarm.getSnooze()); // alarm time

		// Inserting Row
		genid = db.insert(TABLE_ALARMS, null, values);
		
		db.close(); // Closing database connection

		Log.d("addalarm genid:", String.valueOf(genid));
		Log.d("addalarm cast id:", String.valueOf((int)genid));
		
		return (int)genid;	// hm... docs says ID are int but insert returns long
	}

	// Getting single alarm
	AlarmInfo getAlarm(int id) {
		
		SQLiteDatabase db = this.getReadableDatabase();

		Cursor cursor = db.query(
									TABLE_ALARMS, 
									new String[] { KEY_ID, KEY_NAME, KEY_DESCR, KEY_ALARMTIME, KEY_ICON, KEY_ENABLED, KEY_REPEATS, KEY_DAYCODE, KEY_SNOOZE }, 
									KEY_ID + "=?", 
									new String[] { String.valueOf(id) }, 
									null, null, null, null
								);
		if (cursor != null)
			cursor.moveToFirst();

		AlarmInfo alarm = new AlarmInfo(cursor.getInt(0),
										cursor.getString(1), 
										cursor.getString(2), 
										cursor.getLong(3), 
										cursor.getInt(4),
										cursor.getInt(5),
										cursor.getInt(6),
										cursor.getString(7),
										cursor.getInt(8));
		

		Log.d("lsdfhjkshdfkjsdhfkj", alarm.getName());
		return alarm;
	}
	
	// Getting All alarms
	public ArrayList<AlarmInfo> getAllAlarms() {

		ArrayList<AlarmInfo> alarmList = new ArrayList<AlarmInfo>();

		// Select All Query
		String selectQuery = "SELECT  * FROM " + TABLE_ALARMS + " ORDER BY " + KEY_ALARMTIME;

		SQLiteDatabase db = this.getWritableDatabase();
		Cursor cursor = db.rawQuery(selectQuery, null);

		// looping through all rows and adding to list
		if (cursor.moveToFirst()) {
			do {
				AlarmInfo alarm = new AlarmInfo();

				alarm.setID(cursor.getInt(0));
				alarm.setName(cursor.getString(1));
				alarm.setDescription(cursor.getString(2));
				alarm.setAlarmtime(cursor.getLong(3));				
				alarm.setIcon(cursor.getInt(4));				
				alarm.setEnabled(cursor.getInt(5));				
				alarm.setRepeats(cursor.getInt(6));				
				alarm.setDaycode(cursor.getString(7));				
				alarm.setSnooze(cursor.getInt(8));				
				// Adding alarm to list

				alarmList.add(alarm);
				
			} while (cursor.moveToNext());
		}


		db.close();

		
		// return alarm list
		return alarmList;
		
	}

	// Updating single alarm
	public int updateAlarm(AlarmInfo alarm) {
		
		SQLiteDatabase db = this.getWritableDatabase();

		ContentValues values = new ContentValues();
		
		values.put(KEY_NAME, alarm.getName());
		values.put(KEY_DESCR, alarm.getDescription());
		values.put(KEY_ALARMTIME, alarm.getAlarmtime());
		values.put(KEY_ICON, alarm.getIcon());
		values.put(KEY_ENABLED, alarm.getEnabled());
		values.put(KEY_REPEATS, alarm.getRepeats());

		// updating row
		return db.update(TABLE_ALARMS, values, KEY_ID + " = ?", new String[]
				{ 
					String.valueOf(alarm.getID())
				});
		
	}

	// Deleting single alarm
	public void deleteAlarm(AlarmInfo alarm) {
		
		SQLiteDatabase db = this.getWritableDatabase();
		
		db.delete(TABLE_ALARMS, KEY_ID + " = ?", new String[] { String.valueOf(alarm.getID()) });
		
		db.close();
	}


	// Getting alarms Count
	public int getAlarmCount() {
		
		String countQuery = "SELECT  * FROM " + TABLE_ALARMS;
		
		SQLiteDatabase db = this.getReadableDatabase();
		
		Cursor cursor = db.rawQuery(countQuery, null);
		cursor.close();


		return cursor.getCount();
	}
	
	public boolean wipeAll() {

		SQLiteDatabase db = this.getWritableDatabase();

		try {
			db.execSQL("DELETE FROM " + TABLE_ALARMS);
			db.close(); // Closing database connection
			return true;
		} catch (SQLException e) {
			db.close(); // Closing database connection
	        Log.d("Function called: ", e.getMessage());
			return false;
		}
		
		
	}
	
	public boolean dropTable() {

		SQLiteDatabase db = this.getWritableDatabase();

		try {
			db.execSQL("DROP TABLE IF EXISTS " + DATABASE_NAME + "." + TABLE_ALARMS);
			db.close(); // Closing database connection
			return true;
		} catch (SQLException e) {
			db.close(); // Closing database connection
	        Log.d("Function called: ", e.getMessage());
			return false;
		}
		
	
	}


	public void dump_database_to_sdcard() {
		
		String packageName="in.falkeninc.umt_v0_9_8_1";
		String dbList[] = {"alarms"};
		
		
	      try {
              File sd = Environment.getExternalStorageDirectory();
              File data = Environment.getDataDirectory();

              if (sd.canWrite()) {
                  String currentDBPath = "//data//"+ packageName +"//databases//"+dbList[0];
                  String backupDBPath = dbList[0];
                  File currentDB = new File(data, currentDBPath);
                  File backupDB = new File(sd, backupDBPath);

                  @SuppressWarnings("resource")
                  FileChannel src = new FileInputStream(currentDB).getChannel();
                  @SuppressWarnings("resource")
                  FileChannel dst = new FileOutputStream(backupDB).getChannel();
                  dst.transferFrom(src, 0, src.size());
                  src.close();
                  dst.close();
                  Log.d("[DatabaseHandler dunmp DB]", backupDB.toString());
                      //Toast.makeText(g(), backupDB.toString(), Toast.LENGTH_LONG).show();
              }
          } catch (Exception e) {

              //Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
              Log.d("[DatabaseHandler dunmp DB]", e.toString());


          }		
	}
}
